package com.woniuxy.microshoppingcartserver.service.impl;

import com.alibaba.fastjson.JSON;
import com.woniuxy.microcommonserver.bean.gy.GoodsAttributesInfo;
import com.woniuxy.microcommonserver.bean.gy.GoodsInfo;
import com.woniuxy.microshoppingcartserver.bean.CartItem;
import com.woniuxy.microshoppingcartserver.bean.Favorite;
import com.woniuxy.microshoppingcartserver.service.CartService;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

@Service
public class CartServiceImpl implements CartService {
    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private HashOperations hashOperations;

    @Resource
    private ZSetOperations zSetOperations;
    @Resource
    private ValueOperations valueOperations;

    private final String CART_PREFIX = "mail:cart:";
    @Override
    public void addToCart(Integer skuId, Integer nums,Integer goodsId,String userId) {


        //cartKey = mail:cart:userId
        String cartKey = CART_PREFIX + userId;
        //判断redis购物车里有没有该用户添加该商品了吗，有就修改数量，没有就查询商品获得CartItem信息
        if(isAddCart(cartKey,skuId)){
            //如果已经加入购物车
            Object cartItemObject = hashOperations.get(cartKey,skuId.toString());
            CartItem cartItem = JSON.toJavaObject(JSON.parseObject(cartItemObject.toString()),CartItem.class);
            //更新商品数量
            int newNums = cartItem.getNums() + nums;
            cartItem.setNums(newNums);
            cartItem.setCreatTime(new Date().getTime());
            //将新数据储存到redis中,覆盖原来的购物车信息
            hashOperations.put(cartKey,skuId.toString(),JSON.toJSONString(cartItem));
        }else{
            //加入购物车
            CartItem cartItem = findGoodsById(skuId,nums,goodsId);
            hashOperations.put(cartKey,skuId.toString(),JSON.toJSONString(cartItem));
        }


    }

    /**
     * 判断redis缓存中用户购物车是否有该条商品
     * @param cartKey
     * @param skuId skuId
     * @return
     */
    Boolean isAddCart(String cartKey,Integer skuId){
        return hashOperations.hasKey(cartKey,skuId.toString());
    }

    /**
     * 搜索商品信息并转换成购物车对象
     * @param skuId
     * @param nums
     * @return
     */
    /*
    * redis会将object对象序列化，所以存储的时候将对象转换成JSON对象，然后将字符串用户JSON包转换成实体类对象
    * */
    CartItem findGoodsById(Integer skuId,Integer nums,Integer goodsId){
        //根据goodsId和skuId从redis中查询商品信息
        Object goodsInfoJson = valueOperations.get(goodsId.toString());
        GoodsInfo goods = JSON.toJavaObject(JSON.parseObject(goodsInfoJson.toString()),GoodsInfo.class);
        Object attributesInfoJson = valueOperations.get(skuId.toString());
        GoodsAttributesInfo attributesInfo = JSON.toJavaObject(JSON.parseObject(attributesInfoJson.toString()),GoodsAttributesInfo.class);
        CartItem cartItem = new CartItem(skuId,goodsId,true,goods.getGoodsName(),attributesInfo.getGoodDisplayImage(),attributesInfo.getGoodsAttributesList(),attributesInfo.getCostPrice(),nums,attributesInfo.getCostPrice().multiply(BigDecimal.valueOf(nums)),new Date().getTime());
        return cartItem;
    }

    /**
     * 删除
     * @param skuIds 实际上是skuId
     */
    @Override
    public void deleteCart(Integer[] skuIds,String userId) {
        String cartKey = CART_PREFIX + userId;
        for (Integer goodsId:skuIds
             ) {
            if(isAddCart(cartKey,goodsId)){
                hashOperations.delete(cartKey,goodsId);
            }
        }
    }

    /**
     * 修改商品数量
     * @param skuId
     * @param nums
     */
    @Override
    public void updateNumsCart(Integer skuId, Integer nums,String userId) {
        String cartKey = CART_PREFIX + userId;
        //判断商品存在吗
        if(isAddCart(cartKey,skuId)){
            //redis中取出数据
            Object cartItemObject = hashOperations.get(cartKey,skuId.toString());
            CartItem cartItem = JSON.toJavaObject(JSON.parseObject(cartItemObject.toString()),CartItem.class);
            cartItem.setNums(cartItem.getNums()+nums);
            cartItem.setCreatTime(new Date().getTime());
            //redis覆盖原来的数据
            hashOperations.put(cartKey,skuId.toString(),cartItem);
        }
    }

    /**
     * 修改商品型号参数
     * @param
     */
    @Override
    public void updateTypeCart(Integer oldSkuId,Integer newSkuId,String userId) {
        String cartKey = CART_PREFIX + userId;
        //判断商品存在吗
        if(isAddCart(cartKey,oldSkuId)){
            //redis中取出数据旧数据
            Object cartItemObject = hashOperations.get(cartKey,oldSkuId.toString());
            CartItem cartItemOld = JSON.toJavaObject(JSON.parseObject(cartItemObject.toString()),CartItem.class);
            int newNums = cartItemOld.getNums();
            //搜索新商品并包装成购物车对象
            CartItem cartItemNew = findGoodsById(newSkuId,newNums,cartItemOld.getGoodsId());
            //增加到缓存中
            hashOperations.put(cartKey,newSkuId.toString(),JSON.toJSONString(cartItemNew));
            //redis删除旧的
            hashOperations.delete(cartKey,oldSkuId.toString());
        }

    }

    @Override
    public List<CartItem> lookCart(Integer start, Integer end,String userId) {
        String cartKey = CART_PREFIX + userId;
        //根据用户id获得该用户购物车里的所有物品
        Map map = hashOperations.entries(cartKey);
        map.forEach((k,v)->{
            //时间作为score存储到zset中
            CartItem cartItem = JSON.toJavaObject(JSON.parseObject(v.toString()),CartItem.class);
            zSetOperations.add(cartKey+":look",v,cartItem.getCreatTime());
        });
        Set<DefaultTypedTuple<String>> typedTupleSet = zSetOperations.reverseRangeByScoreWithScores(cartKey+":look",Double.NEGATIVE_INFINITY,Double.POSITIVE_INFINITY,start,end);
        List<CartItem> items = new ArrayList<>();
        typedTupleSet.forEach(e->{
            items.add(JSON.toJavaObject(JSON.parseObject(e.getValue().toString()),CartItem.class));
        });
        return items;
    }


}
